package com.exception.demo.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import com.alibaba.fastjson.JSON;
import com.exception.demo.annotation.LogAnnotation;

/**
 * @ClassName: LogAop
 * @Description: 自定义日志注解
 * @author ldq
 * @date 2020-03-29 19:50:24
 */
@Aspect
@Configuration
public class LogAop {
	private static final Logger log = LoggerFactory.getLogger("LogAop");

	/**
	 * 1，表示在哪个类的哪个方法进行切入。配置有切入点表达式。 2，对有@LogAnnotation标记的方法,记录其执行参数及返回结果。
	 */
	@Pointcut("execution(* com.exception.demo.controller..*.*(..)) && @annotation(com.exception.demo.annotation.LogAnnotation)")
	public void controllerAspect() {}

	@Around(value = "@annotation(com.exception.demo.annotation.LogAnnotation)")
	public Object log(ProceedingJoinPoint joinPoint) throws Throwable {

		// 获取参数名
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		LogAnnotation logAnnotation = methodSignature.getMethod().getDeclaredAnnotation(LogAnnotation.class);

		long startTime = System.currentTimeMillis();
		
		log.info("请求开始：执行类及方法={}，参数名={}，参数值={}", methodSignature, 
				JSON.toJSON(methodSignature.getParameterNames()), JSON.toJSON(joinPoint.getArgs()));
		// 执行原方法，并记录返回值
		Object object = joinPoint.proceed();

		//Object[] args = joinPoint.getArgs(); //参数名称
		//String[] argNames = methodSignature.getParameterNames();//参数值
		//log.info("信息：{}", methodSignature);
		//log.info("类名：{}", methodSignature.getDeclaringTypeName());
		//log.info("方法名：{}", methodSignature.getName());
		
		log.info("请求结束：执行类及方法={}，方法描述={}，返回值={}，execute time={}", 
				methodSignature, logAnnotation.desc(), JSON.toJSON(object), (System.currentTimeMillis() - startTime));

		return object;

	}
}
